﻿#region Copyright Statement
//  ------------------------------------------------------------------------------
//  
//    This file is part of The Streambolics Library.
//    Copyright © 2005-2009, Stephan Leclercq & Streambolics
//    All rights reserved.
//  
//    The Streambolics Library is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//  
//    The Streambolics Library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//  
//    You should have received a copy of the GNU General Public License
//    along with Streambolics; if not, write to the Free Software
//    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//  
//  ------------------------------------------------------------------------------
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using Streambolics.PatLite;

namespace DemoApp
{
    public partial class MainForm : Form
    {
        private PhcLightpole _Lightpole = new PhcLightpole ();
        private bool _donemanually;
        private int _Count;
        private Random _Random = new Random ();
        private string _NewStatus;

        public MainForm ()
        {
            InitializeComponent ();
        }

        private void serial_DataReceived (object sender, SerialDataReceivedEventArgs e)
        {
            ReadResponse ();
        }

        private void ReadResponse ()
        {
            if (serial.IsOpen)
            {
                int n = serial.BytesToRead;
                if (n > 0)
                {
                    byte[] m = new byte[n];
                    serial.Read (m, 0, n);
                    _Lightpole.ConsumeMessage (m);
                }
            }
        }

        private void timer_Tick (object sender, EventArgs e)
        {
            if (_NewStatus != null)
            {
                edit_Status.Text = _NewStatus;
                _NewStatus = null;
            }

            if (!serial.IsOpen && !_donemanually)
            {
                check_PortOpen.Checked = true;
            }

            if (_Count > 250)
            {
                _Count = 0;
                combo_Red.SelectedIndex = _Random.Next (3);
                combo_Green.SelectedIndex = _Random.Next (3);
                combo_Amber.SelectedIndex = _Random.Next (3);
            }
            else
            {
                _Count++;
            }

            byte[] m = _Lightpole.ProduceMessage ();
            if (m != null)
            {
                if (serial.IsOpen)
                {
                    serial.Write (m, 0, m.Length);
                }
                StringBuilder sb = new StringBuilder ();
                foreach (byte b in m)
                {
                    sb.AppendFormat ("{0} ", b);
                }
                foreach (byte b in m)
                {
                    sb.AppendFormat ("{0}", (char)b);
                }
                sb.Append ("\r\n");
                edit_LastMessage.Text += sb.ToString ();
            }
            else
            {
                ReadResponse ();
            }
        }

        private void combo_Red_SelectedIndexChanged (object sender, EventArgs e)
        {
            _Lightpole.Red = ComboToLamp (combo_Red);
        }

        private Lamp ComboToLamp (ComboBox c)
        {
            switch (c.SelectedIndex)
            {
                case 0:
                    return Lamp.Off;
                case 1:
                    return Lamp.Flashing;
                case 2:
                    return Lamp.On;
                default:
                    return Lamp.Unknown;
            }
        }

        private void check_PortOpen_CheckedChanged (object sender, EventArgs e)
        {
            _donemanually = true;
            if (check_PortOpen.Checked)
            {
                serial.Open ();
            }
            else
            {
                serial.Close ();
            }
            ReportPortStatus ();
        }

        private void combo_Green_SelectedIndexChanged (object sender, EventArgs e)
        {
            _Lightpole.Green = ComboToLamp (combo_Green);
        }

        private void combo_Amber_SelectedIndexChanged (object sender, EventArgs e)
        {
            _Lightpole.Amber = ComboToLamp (combo_Amber);
        }

        private void serial_PinChanged (object sender, SerialPinChangedEventArgs e)
        {
            ReportPortStatus ();
            if (e.EventType == SerialPinChange.CtsChanged)
            {
                _Lightpole.PeerReset ();
            }
        }

        private void ReportPortStatus ()
        {
            StringBuilder sb = new StringBuilder ();
            if (serial.IsOpen)
            {
                sb.Append ("Open ");
                if (serial.BreakState)
                {
                    sb.Append ("Break ");
                }
                if (serial.CDHolding)
                {
                    sb.Append ("CD ");
                }
                if (serial.CtsHolding)
                {
                    sb.Append ("CTS ");
                }
                if (serial.DsrHolding)
                {
                    sb.Append ("DSR ");
                }
            }
            else
            {
                sb.Append ("Closed ");
            }

            _NewStatus = sb.ToString ();
        }

        private void combo_Siren_SelectedIndexChanged (object sender, EventArgs e)
        {
            _Lightpole.Siren = comboToSiren (combo_Siren);
        }

        private Siren comboToSiren (ComboBox combo_Siren)
        {
            switch (combo_Siren.SelectedIndex)
            {
                case 0:
                    return Siren.Off;
                case 1:
                    return Siren.Slow;
                case 2:
                    return Siren.Fast;
                default:
                    return Siren.Unknown;
            }
        }
    }
}
